﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace CS_Util {
    public static class C_Log {
        public static I_Log o_logObj;
        public static void Log(object message, bool isShowStackTrace = false) {
            Log(3, message, isShowStackTrace);
        }
        public static void LogFormat(string format, params object[] args) {        
            try {
                string message = string.Format(format, args);
                Log(3, message,true);
            } catch (Exception ex){
                string msg = "string.Format()解析错误_" + format + "____" + args.ToStringLog() + "____" + ex.Message;
                Log(0, msg, true);
                Console.WriteLine(msg);
            }          
        }
        public static void LogInfo(string message, string stackTrace, bool isAddStackTrace = false) {
            LogStackTrace(3, message, stackTrace, isAddStackTrace);
        }

        public static void LogError(object message, bool isShowStackTrace = false) {
            Log(0, message, isShowStackTrace);
        }
        public static void LogErrorFormat(string format, params object[] args) {           
            string message = null;
            if (args.Length == 0) {
                message = format;
            } else {
                message = string.Format(format, args);
            }
            Log(0, message,true);           
        }
        public static void LogError(string message, string stackTrace, bool isAddStackTrace = false) {
            LogStackTrace(0, message, stackTrace, isAddStackTrace);          
        }
        public static void LogErrorInfo(string message, Exception ex, string stackTraceEnd = null) {
            LogStackTrace(0, message+"__"+ex.Message, ex.S_GetInfo("",0, stackTraceEnd));
        }
        public static void LogErrorInfo2(string message, Exception ex, StackTrace exEnd) {
            string stackTraceEnd = null;
            if (exEnd != null) {
                stackTraceEnd = S_GetInfo("", exEnd);
            }
            LogStackTrace(0, message + "__" + ex.Message, ex.S_GetInfo("", 0, stackTraceEnd));
        }


        public static void LogWarning(object message, bool isShowStackTrace = false) {
            Log(2, message, isShowStackTrace);
        }     
        public static void LogWarningFormat(string format, params object[] args) {       
            string message = null;
            if (args.Length == 0) {
                message = format;
            } else {
                message = string.Format(format, args);
            }
            Log(2, message,true);         
        }



        public static void LogException(string message) {
            Log(4, message, true);
        }
        public static void LogExceptionFormat(string format, params object[] args) {
            string message = null;
            if (args.Length == 0) {
                message = format;
            } else {
                message = string.Format(format, args);
            }
            Log(4, message, true);
        }

        public static void Log(byte type, object message, bool isShowStackTrace = false) {
            if (o_logObj != null) {
                string stackTrace = "";
                if (isShowStackTrace) {
                    stackTrace = C_Log.S_GetInfo("", null, 3);
                }
                o_logObj.S_Log(type, "nullTag", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), message.ToString(), stackTrace);
            }
        }
        public static void LogStackTrace(byte type, object message, string stackTrace, bool isAddStackTrace = false) {
            if (o_logObj != null) {
                if (isAddStackTrace) {
                    stackTrace += C_Log.S_GetInfo("", null, 1);
                }
                o_logObj.S_Log(type, "nullTag", "4222555", message.ToString(), stackTrace);
            }
        }

        public static void S_Log(byte type, string tag, string time, string log, string stackTrace) {
            if (o_logObj != null) {
                o_logObj.S_Log(type, tag, time, log, stackTrace);
            }
        }







        public static string S_GetInfo(this Exception ex,string message="", int shieldLine = 0, string end = "") {
            StackTrace st = new StackTrace(ex, true);
            string message1= string.Format("{0}...{1}", message, ex.Message);
            return S_GetInfo(message1, st, shieldLine, end);
        }

        public static string S_GetInfo(string message, StackTrace st = null,int ShieldLine=0,string end="") {
            if (st == null) {
                st = new StackTrace(true);
            }
            if (string.IsNullOrEmpty(message) == false) {
                message = message + "\nstackTrace==";
            }
            StringBuilder ssb = new StringBuilder(message);
            StackFrame[] frames = st.GetFrames();
            for(int i= ShieldLine; i< frames.Length;i++) {
                string fileName = frames[i].GetFileName();
                if (string.IsNullOrEmpty(fileName)) {
                    continue;
                }
                MethodBase method = frames[i].GetMethod();
                string methodName = "null";
                if (method != null && method.Name != null) { methodName = method.ToString(); }
                if (i < frames.Length - 1) {
                    ssb.AppendFormat("{0} (at {1}:{2})\n", methodName, fileName.Replace("\\", "/").Substring(0), frames[i].GetFileLineNumber());
                } else {
                    ssb.AppendFormat("{0} (at {1}:{2})", methodName, fileName.Replace("\\", "/").Substring(0), frames[i].GetFileLineNumber());
                }
                //if (i < frames.Length - 1) {
                //    ssb.AppendFormat("(at {0}:{1}) {2} \n", fileName.Replace("\\", "/").Substring(31), frames[i].GetFileLineNumber(), methodName);
                //} else {
                //    ssb.AppendFormat("(at {0}:{1}) {2} ", fileName.Replace("\\", "/").Substring(31), frames[i].GetFileLineNumber(), methodName);
                //}
            }
            ssb.Append(end);
            return ssb.ToString();
        }

    }

    public interface I_Log {
        void S_Log(byte type,string tag, string time, string log, string stackTrace);
    }
    public enum LogType0 { 
        Error = 0,
        Assert = 1, 
        Warning = 2,
        Log = 3,
        Exception = 4
    }
}
